package fire.and.near.challenger;

import java.util.List;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.facebook.FacebookException;
import com.facebook.Response;
import com.facebook.model.GraphUser;

import fire.and.near.challenger.database.ChallengeModel;
import fire.and.near.challenger.database.DatabaseActivity;
import fire.and.near.challenger.database.DatabaseAsyncTask;
import fire.and.near.challenger.database.DatabaseAsyncTask.DatabaseQueryOptions;
import fire.and.near.challenger.database.DatabaseResponse;
import fire.and.near.challenger.database.DefaultChallengesManager;
import fire.and.near.challenger.database.ProfileManager;
import fire.and.near.challenger.facebook.FacebookActionAdapter;
import fire.and.near.challenger.facebook.FacebookHelper;
import fire.and.near.challenger.util.ChallengeUtil;
import fire.and.near.challenger.util.Consts;
import fire.and.near.challenger.web.HttpRequestSender;
import fire.and.near.challenger.web.HttpRequestSender.RequestOptions;
import fire.and.near.challenger.web.ServerResponse;
import fire.and.near.challenger.web.WebActivity;

/**
 * 
 * @author NeaR
 * 
 */
public class LoginActivity extends Activity implements DatabaseActivity,
		WebActivity {

	private EditText mEditTextUsername = null;
	private EditText mEditTextPassword = null;
	private Button mButtonLogin = null;

	public static FacebookHelper mFbHelper = null;

	private DatabaseAsyncTask mDbAddChallengesTask = null;
	private HttpRequestSender mHttpGetChallengesTask = null;
	private HttpRequestSender mHttpUpdateChallengesTask = null;

	private ProfileManager mProfileManager = null;
	
	private List<ChallengeModel> pendingChallenges = null;

	private boolean mIsOnlineMode = false;

	private int mAsyncTaskCounter = 0;
	private final int ASYNC_TASK_COUNT = 4;

	private long mFbId = 0;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_login);

		final Context context = this;

		mFbHelper = new FacebookHelper();

		mProfileManager = new ProfileManager(this);

		if (savedInstanceState == null) {
			Log.i("onCreate", "in if savedinstancestate");

			mEditTextUsername = (EditText) findViewById(R.id.editText_username);
			mEditTextUsername.setVisibility(View.GONE);

			mEditTextPassword = (EditText) findViewById(R.id.editText_password);
			mEditTextPassword.setVisibility(View.GONE);

			mButtonLogin = (Button) findViewById(R.id.button_login);
			mButtonLogin.setVisibility(View.GONE);
		}

		Log.i("onCreate", "before network check");
		if (HttpRequestSender.isNetworkAvailable(this)) {
			mIsOnlineMode = true;

			Log.i("onCreate", "after network check");

			try {
				mFbHelper.login(this, new FacebookActionAdapter() {
					@Override
					public void onLoginCompleted(GraphUser user,
							Response response) {

						if (response.getError() == null) {
							updateStatusCompleted(R.id.textView_fb_login_success);

							mFbId = Long.parseLong(user.getId());

							Log.i("onCreate", "FB ID:" + mFbId);

							if (mProfileManager.getFbId() < 0) {
								// user should register
								mProfileManager.setFbId(mFbId);
								mButtonLogin.setText("Register");
								enableControls(true);
							} else {
								mAsyncTaskCounter++;
							}

							// Get New Challenges
							mHttpGetChallengesTask = new HttpRequestSender(
									RequestOptions.DOWNLOAD_CHALLENGES,
									(Activity) context);
							mHttpGetChallengesTask.execute(mFbId);

							// Update Default Challenges
							mHttpUpdateChallengesTask = new HttpRequestSender(
									RequestOptions.UPDATE_CHALLENGES,
									(Activity) context);
							mHttpUpdateChallengesTask.execute(DefaultChallengesManager
									.getLastDefaultChallengeId(context));
							
							if (mFbId != 0) {
								new DatabaseAsyncTask(context, DatabaseQueryOptions.PENDING_FOR_FB)
										.execute(mFbId);
							}
						} else {
							mIsOnlineMode = false;
							Log.e("FB_ERR", response.getError().toString());
						}
					}
				});
			} catch (FacebookException ex) {
				mIsOnlineMode = false;
			}
		} else {
			mIsOnlineMode = false;
		}

		if (!mIsOnlineMode) {
			enableControls(true);
			((TextView) findViewById(R.id.textView_fb_login_success))
					.setVisibility(View.GONE);
			((TextView) findViewById(R.id.textView_download_challenges_success))
					.setVisibility(View.GONE);
			((TextView) findViewById(R.id.textView_upload_challenges_success))
					.setVisibility(View.GONE);
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		mFbHelper.onActivityResult(this, requestCode, resultCode, data);
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		outState.putInt("mAsyncTaskCounter", mAsyncTaskCounter);
		
		super.onSaveInstanceState(outState);
	}

	@Override
	protected void onRestoreInstanceState(Bundle savedInstanceState) {
		this.mAsyncTaskCounter = savedInstanceState
				.getInt("mAsyncTaskCounter");
		
		super.onRestoreInstanceState(savedInstanceState);
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		return true;
	}

	@Override
	public void processSeverResponse(ServerResponse response) {
		if (response == null) {

		}
		switch (response.getRequestOption()) {
		
		case UPDATE_CHALLENGES:
			updateStatusCompleted(R.id.textView_upload_challenges_success);
			break;
		case DOWNLOAD_CHALLENGES:

			if (response.getStatusCode() == Consts.HTTP_OK) {
				@SuppressWarnings("unchecked")
				final List<ChallengeModel> challenges = (List<ChallengeModel>) response
						.getData();

				final Context context = this;
				mFbHelper.getFriends(this, new FacebookActionAdapter() {

					@Override
					public void onGetFriends(List<GraphUser> users,
							Response response) {

						// mb in background?
						fillFriendsNames(users, challenges);

						mDbAddChallengesTask = new DatabaseAsyncTask(context,
								DatabaseQueryOptions.INSERT_CHALLENGES);

						mDbAddChallengesTask.execute(challenges);
					}

					private void fillFriendsNames(List<GraphUser> users,
							List<ChallengeModel> challenges) {
						boolean found = false;

						for (int i = 0; i < challenges.size(); i++) {
							found = false;

							for (int j = 0; j < users.size(); j++) {
								if (challenges.get(i).getChallenger().getFbID() == Long
										.parseLong(users.get(j).getId())) {
									challenges.get(i).getChallenger()
											.setName(users.get(j).getName());
									found = true;
									break;
								}
							}

							if (!found) {
								challenges.remove(i);
								i--;
							}
						}
					}
				});

			} else {
				mAsyncTaskCounter++;
			}

			mAsyncTaskCounter++;
			break;
		default:
			break;
		}

		if (checkAsyncReady()) {
			continueToPendingChallenges();
		}
	}

	@Override
	public void setHttpWorking(boolean working) {

	}

	@Override
	public void processDatabaseResponse(DatabaseResponse result) {
		switch (result.getOption()) {
		case PENDING_FOR_FB:
			this.pendingChallenges = (List<ChallengeModel>) result
					.getData();

			mAsyncTaskCounter++;

			break;
		case INSERT_CHALLENGES:
			if (result.isSuccessful()) {
				Log.i("INSERT_CHALLENGES", "success");
			} else {
				Log.i("INSERT_CHALLENGES", "fail");
			}

			mAsyncTaskCounter++;
			updateStatusCompleted(R.id.textView_download_challenges_success);

			break;
		default:
			break;
		}

		if (checkAsyncReady()) {
			conitnueNext();
		}
	}
	
	private void conitnueNext() {
		
		if (this.pendingChallenges != null) {
			if (this.pendingChallenges.size() == 0) {
				continueToMain();
			} else {
				continueToPendingChallenges();
			}
		} else {
			continueToMain();
		}
		
	}

	private void enableControls(boolean enable) {
		mEditTextUsername.setVisibility(enable ? View.VISIBLE : View.GONE);
		mEditTextPassword.setVisibility(enable ? View.VISIBLE : View.GONE);
		mButtonLogin.setVisibility(enable ? View.VISIBLE : View.GONE);
	}

	@Override
	public void setDatabaseWorking(boolean working) {
		// TODO Auto-generated method stub

	}

	@SuppressLint("NewApi")
	public void tryLogin(View view) {
		String username = mEditTextUsername.getText().toString().trim();
		String password = mEditTextPassword.getText().toString().trim();

		if (username.isEmpty() || password.isEmpty()) {
			Toast.makeText(this, "Missing username or password",
					Toast.LENGTH_LONG).show();
			return;
		}

		if (mIsOnlineMode) {
			if (mProfileManager.register(mFbId, username, password)) {
				mAsyncTaskCounter++;
				enableControls(false);

				if (checkAsyncReady()) {
					conitnueNext();
				}
			}
		} else {
			if (mProfileManager.login(username, password)) {
				conitnueNext();
			} else {
				Toast.makeText(this, "Wrong username or password",
						Toast.LENGTH_SHORT).show();
			}
		}
	}

	private boolean checkAsyncReady() {
		return mAsyncTaskCounter == ASYNC_TASK_COUNT;
	}
	
	private void continueToMain() {
		Intent intent = new Intent(this, MainActivity.class);
		startActivity(intent);
		finish();
	}

	private void continueToPendingChallenges() {
		Intent intent = new Intent(this, PendingChallengesActivity.class);
		String challengesJsonString = ChallengeUtil.challengeListToJsonString(pendingChallenges);
		intent.putExtra(Consts.CHALLENGES_JSON_EXTRA, challengesJsonString);
		startActivity(intent);
		finish();
	}

	private void updateStatusCompleted(int resId) {
		((TextView) findViewById(resId))
				.setCompoundDrawablesWithIntrinsicBounds(
						null,
						null,
						getResources().getDrawable(
								R.drawable.com_facebook_button_check_on), null);
	}

}
